package com.dmap.analysispoint.service.impl;

import com.dmap.analysispoint.bo.DataBoardBo;
import com.dmap.analysispoint.constants.BurialPointConstant;
import com.dmap.analysispoint.controller.background.param.CountParam;
import com.dmap.analysispoint.dao.BurialPointAddAndActivePhoneMapper;
import com.dmap.analysispoint.po.BurialPointAddAndActivePhone;
import com.dmap.analysispoint.rpc.RpcAppInfoService;
import com.dmap.analysispoint.rpc.RpcCompanyInfoService;
import com.dmap.analysispoint.service.*;
import com.dmap.base.cache.impl.BaseCacheDaoStringImpl;
import com.dmap.base.units.DateUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * \* @author:zhouhao
 * \* Date:23/06/2018
 * \* Description:数据预处理
 * \*
 */
@Service
public class DataPreparationServiceImpl extends BaseCacheDaoStringImpl implements DataPreparationService {

    private static final Logger logger = LoggerFactory.getLogger(DataPreparationServiceImpl.class);

    @Resource
    private PhoneInfoAnalysisService phoneInfoAnalysisService;
    @Resource
    private SelectAllCompanyIdByProjectIdService SelectAllCompanyIdByProjectIdService;
    @Resource
    private EquipmentInfoAnalysisService equipmentInfoAnalysisService;
    @Resource
    private CacheUtilsService cacheUtilsService;
    @Resource
    private GetCompanyIdService getCompanyIdService;
    @Resource
    private BurialPointAddAndActivePhoneMapper burialPointAddAndActivePhoneMapper;
    @Resource
    private RpcCompanyInfoService rpcCompanyInfoService;
    @Resource
    private RpcAppInfoService rpcAppInfoService;

    @Override
    public Integer countPhoneEquipmentNumAndAddCache(Long startTime, Long endTime) {
        if (startTime == null || endTime == null || endTime == 0) {
            return 0;
        }
        int success = 0;
        //定义暂时保存新增手机数、活跃手机数、累积手机数、累积设备数的变量
        int addPhoneNum;
        int activePhoneNum;
        int allPhoneNum;
        int allEquipmentNum;

        //获取所有项目的ProjectId
        List<String> projectIdList = rpcAppInfoService.selectAllProjectId();
        //获取项目级数据并加入缓存(前缀ProjectId)
        for (String projectId : projectIdList) {
            DataBoardBo dataBoardBo = new DataBoardBo();
            CountParam countParam = new CountParam();
            countParam.setProjectId(projectId);
            countParam.setStartTime(startTime);
            countParam.setEndTime(endTime);
            addPhoneNum = phoneInfoAnalysisService.countAddPhoneNum(countParam);
            activePhoneNum = phoneInfoAnalysisService.countActivePhoneNumByBurialPoint(projectId, startTime, endTime);
            countParam.setStartTime(0L);
            allPhoneNum = phoneInfoAnalysisService.countAddPhoneNum(countParam);
            allEquipmentNum = equipmentInfoAnalysisService.countEquipmentNum(countParam);
            dataBoardBo.setAddPhoneNum(addPhoneNum);
            dataBoardBo.setActivePhoneNum(activePhoneNum);
            dataBoardBo.setAllPhoneNum(allPhoneNum);
            dataBoardBo.setAllEquipmentNum(allEquipmentNum);
            String cacheKey = BurialPointConstant.CACHE_ANALYSIS_POINT_PROJECT_INFO_CODE + projectId;
            cacheUtilsService.addCache(dataBoardBo, cacheKey);
            success++;
        }
        //判断是否刷新项目级缓存
        if (success > 0) {
            success = 1;
        }

        //获取所有分公司的companyId
        List<Long> companyIdList = SelectAllCompanyIdByProjectIdService.selectCompanyIdByProjectId(projectIdList);
        //获取分公司级数据并加入缓存(前缀companyId)
        for (Long companyId : companyIdList) {
            addPhoneNum = 0;
            activePhoneNum = 0;
            allPhoneNum = 0;
            allEquipmentNum = 0;
            DataBoardBo dataBoardBo = new DataBoardBo();
            List<String> companyProjectList = rpcCompanyInfoService.selectByCompanyId(companyId);
            for (String projectId : companyProjectList) {
                String value = getKV(BurialPointConstant.CACHE_ANALYSIS_POINT_PROJECT_INFO_CODE + projectId);
                if (StringUtils.isNotBlank(value)) {
                    DataBoardBo dataBoardCacheBo = new DataBoardBo();
                    ObjectMapper mapper = new ObjectMapper();
                    try {
                        dataBoardCacheBo = mapper.readValue(value, DataBoardBo.class);
                    } catch (Exception e) {
                        logger.error("String to dataBoardCacheBo(前缀companyId) error" + e);
                    }
                    addPhoneNum = addPhoneNum + dataBoardCacheBo.getAddPhoneNum();
                    activePhoneNum = activePhoneNum + dataBoardCacheBo.getActivePhoneNum();
                    allPhoneNum = allPhoneNum + dataBoardCacheBo.getAllPhoneNum();
                    allEquipmentNum = allEquipmentNum + dataBoardCacheBo.getAllEquipmentNum();
                }
            }
            dataBoardBo.setAddPhoneNum(addPhoneNum);
            dataBoardBo.setActivePhoneNum(activePhoneNum);
            dataBoardBo.setAllPhoneNum(allPhoneNum);
            dataBoardBo.setAllEquipmentNum(allEquipmentNum);
            String cacheKey = BurialPointConstant.CACHE_ANALYSIS_POINT_COMPANY_INFO_CODE + companyId;
            cacheUtilsService.addCache(dataBoardBo, cacheKey);
            success++;
        }
        //判断是否刷新分公司级缓存
        if (success > 1) {
            success = 2;
        }

        //获取总公司级数据并加入缓存(前缀总公司)
        addPhoneNum = 0;
        activePhoneNum = 0;
        allPhoneNum = 0;
        allEquipmentNum = 0;
        DataBoardBo dataBoardBo = new DataBoardBo();
        for (Long companyId : companyIdList) {
            String value = getKV(BurialPointConstant.CACHE_ANALYSIS_POINT_COMPANY_INFO_CODE + companyId);
            if (StringUtils.isNotBlank(value)) {
                DataBoardBo dataBoardCacheBo = new DataBoardBo();
                ObjectMapper mapper = new ObjectMapper();
                try {
                    dataBoardCacheBo = mapper.readValue(value, DataBoardBo.class);
                } catch (Exception e) {
                    logger.error("String to dataBoardCacheBo(前缀总公司) error" + e);
                }
                addPhoneNum = addPhoneNum + dataBoardCacheBo.getAddPhoneNum();
                activePhoneNum = activePhoneNum + dataBoardCacheBo.getActivePhoneNum();
                allPhoneNum = allPhoneNum + dataBoardCacheBo.getAllPhoneNum();
                allEquipmentNum = allEquipmentNum + dataBoardCacheBo.getAllEquipmentNum();
            }
        }
        dataBoardBo.setAddPhoneNum(addPhoneNum);
        dataBoardBo.setActivePhoneNum(activePhoneNum);
        dataBoardBo.setAllPhoneNum(allPhoneNum);
        dataBoardBo.setAllEquipmentNum(allEquipmentNum);
        String cacheKey = BurialPointConstant.CACHE_ANALYSIS_POINT_CORPORATION_INFO_CODE;
        cacheUtilsService.addCache(dataBoardBo, cacheKey);
        success++;
        //判断是否刷新总公司级缓存
        if (success > 2) {
            success = 3;
        }
        return success;
    }

    @Override
    @Transactional
    public Integer dataBoardAnalysis(Long startTime, Long endTime) {
        if (startTime == null || endTime == null || endTime == 0) {
            return 0;
        }
        //定义所需要的时间段
        long theWeekStartTime = DateUtil.getTheFirstDayOfWeek(startTime);
        long theWeekEndTime = endTime;
        long lastWeekStartTime = theWeekStartTime - BurialPointConstant.ONE_DAY_TIME_MILLISECONDS * 7;
        long lastWeekEndTime = theWeekEndTime - BurialPointConstant.ONE_DAY_TIME_MILLISECONDS * 7;
        long theMonthStartTime = DateUtil.getTheFistDayOfMonthDays(startTime);
        long theMonthEndTime = endTime;
        long lastMonthStartTime = DateUtil.getPreMonthStartAndEndTime(startTime).get("startTime");
        long lastMonthEndTime = theMonthEndTime - (theMonthStartTime - lastMonthStartTime);

        List<BurialPointAddAndActivePhone> burialPointAddAndActivePhoneList = new ArrayList<>();

        //获取所有项目的ProjectId
        List<String> projectIdList = rpcAppInfoService.selectAllProjectId();
        for (String projectId : projectIdList) {
            CountParam param = new CountParam();
            param.setProjectId(projectId);
            BurialPointAddAndActivePhone burialPointAddAndActivePhone = new BurialPointAddAndActivePhone();
            burialPointAddAndActivePhone.setProjectId(projectId);
            //获得该projectId所属公司的Id
            long companyId = getCompanyIdService.getCompanyIdByProjectId(projectId);
            burialPointAddAndActivePhone.setCompanyId(companyId);
            //获得活跃手机数
            param.setStartTime(startTime);
            param.setEndTime(endTime);
            int activePhoneNum = phoneInfoAnalysisService.countActivePhoneNumByDay(param);
            burialPointAddAndActivePhone.setActivePhoneNum(activePhoneNum);

            //获得新增手机数
            int  addPhoneNum = phoneInfoAnalysisService.countAddPhoneNum(param);
            burialPointAddAndActivePhone.setAddPhoneNum(addPhoneNum);

            //获得本周活跃手机数
            param.setStartTime(theWeekStartTime);
            param.setEndTime(theWeekEndTime);
            int thisWeekActivePhoneNum = phoneInfoAnalysisService.countActivePhoneNumByDay(param);
            burialPointAddAndActivePhone.setThisWeekActivePhoneNum(thisWeekActivePhoneNum);

            //获得上周同比本周同时期活跃手机数
            param.setStartTime(lastWeekStartTime);
            param.setEndTime(lastWeekEndTime);
            int lastWeekActivePhoneNum = phoneInfoAnalysisService.countActivePhoneNumByDay(param);
            burialPointAddAndActivePhone.setLastWeekActivePhoneNum(lastWeekActivePhoneNum);

            //获得本月活跃手机数
            param.setStartTime(theMonthStartTime);
            param.setEndTime(theMonthEndTime);
            int thisMonthActivePhoneNum = phoneInfoAnalysisService.countActivePhoneNumByDay(param);
            burialPointAddAndActivePhone.setThisMonthActivePhoneNum(thisMonthActivePhoneNum);

            //获得上月同比本月同时期活跃手机数
            param.setStartTime(lastMonthStartTime);
            param.setEndTime(lastMonthEndTime);
            int lastMonthActivePhoneNum = phoneInfoAnalysisService.countActivePhoneNumByDay(param);
            burialPointAddAndActivePhone.setLastMonthActivePhoneNum(lastMonthActivePhoneNum);

            burialPointAddAndActivePhone.setCreateTime(startTime);
            burialPointAddAndActivePhoneList.add(burialPointAddAndActivePhone);
        }
        return burialPointAddAndActivePhoneMapper.insertBatch(burialPointAddAndActivePhoneList);
    }
}
